package com.lwl.leetcode.滑动窗口;

import com.lwl.Utils.PrintUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * @author lwl
 * @Description 503. 下一个更大元素 II
 * 中等
 * 相关标签
 * conpanies icon
 * 相关企业
 * 给定一个循环数组 nums （ nums[nums.length - 1] 的下一个元素是 nums[0] ），返回 nums 中每个元素的 下一个更大元素 。
 * 数字 x 的 下一个更大的元素 是按数组遍历顺序，这个数字之后的第一个比它更大的数，这意味着你应该循环地搜索它的下一个更大的数。如果不存在，则输出 -1 。
 * 示例 1:
 * 输入: nums = [1,2,1]
 * 输出: [2,-1,2]
 * 解释: 第一个 1 的下一个更大的数是 2；
 * 数字 2 找不到下一个更大的数；
 * 第二个 1 的下一个最大的数需要循环搜索，结果也是 2。
 * @date 2025/9/1 16:01
 */
public class Code053NextGreaterElements {
    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4, 3};
        int[] res = nextGreaterElements(nums);
        PrintUtil.printArray(res);
    }

    public static int[] nextGreaterElements(int[] nums) {
        int[] newNums = new int[nums.length * 2];
        int[] res = new int[nums.length * 2];
        int index = 0;
        for (int j = 0; j < 2; j++) {
            for (int i = 0; i < nums.length; i++) {
                newNums[index++] = nums[i];
            }
        }
        // 从左往右递减的单调栈
        LinkedList<List<Integer>> queue = new LinkedList<>();
        for (int i = 0; i < newNums.length; i++) {
            while (!queue.isEmpty() && newNums[i] > newNums[queue.peekLast().get(0)]) {
                List<Integer> list = queue.pollLast();
                for (Integer e : list) {
                    res[e] = newNums[i];
                }
            }
            if (!queue.isEmpty() && newNums[i] == newNums[queue.peekLast().get(0)]) {
                queue.peekLast().add(i);
            } else {
                ArrayList<Integer> list = new ArrayList<>();
                list.add(i);
                queue.addLast(list);
            }
        }
        while (!queue.isEmpty()) {
            List<Integer> list = queue.pollLast();
            for (Integer e : list) {
                res[e] = -1;
            }
        }
        return Arrays.copyOfRange(res, 0, nums.length);
    }
}
